/*
 * serializable.c
 *
 *  Created on: 12/11/2011
 *      Author: utn_so
 */

#include "serializable.h"
#include <string.h>
#include <stdlib.h>

void Serializable_Free(Serializable_t *aSerializable)
{
	if(aSerializable->Data != NULL)
		free(aSerializable->Data);
	aSerializable->Size = 0;
}

void Serialize_Message(Serializable_t * aSerializable, Message aMessage)
{
	/*
	TypeMsg type;
	uint32_t auxiliar;
	int32_t sectorRequest;
	int32_t contentSize;
	char * content;
	*/
	int32_t offset = 0;
	int32_t sizeToAlloc = sizeof(aMessage.type) + sizeof(aMessage.sectorRequest) + sizeof(aMessage.auxiliar) + sizeof(aMessage.contentSize) + aMessage.contentSize * sizeof(char);
	aSerializable->Data = calloc(sizeToAlloc, 1);
	memcpy(aSerializable->Data + offset, &(aMessage.type), sizeof(aMessage.type));
	offset += sizeof(aMessage.type);
	memcpy(aSerializable->Data + offset, &(aMessage.auxiliar), sizeof(aMessage.auxiliar));
	offset += sizeof(aMessage.auxiliar);
	memcpy(aSerializable->Data + offset, &(aMessage.sectorRequest), sizeof(aMessage.sectorRequest));
	offset += sizeof(aMessage.sectorRequest);
	memcpy(aSerializable->Data + offset, &(aMessage.contentSize), sizeof(aMessage.contentSize));
	offset += sizeof(aMessage.contentSize);
	memcpy(aSerializable->Data + offset, aMessage.content, aMessage.contentSize * sizeof(char));
	aSerializable->Size = offset + aMessage.contentSize * sizeof(char);
}

void Serializable_EditType(Serializable_t * aSerializable, TypeMsg newType)
{
	memcpy(aSerializable->Data, &(newType), sizeof(newType));
}

void Serializable_EditAuxiliar(Serializable_t * aSerializable, uint32_t newAuxiliar)
{
	uint32_t offset = sizeof(TypeMsg);
	memcpy(aSerializable->Data + offset, &(newAuxiliar), sizeof(newAuxiliar));
}

void Deserialize_Message(Message *aMessage, Serializable_t aSerializable)
{
	/*
	TypeMsg type;
	uint32_t auxiliar;
	int32_t sectorRequest;
	int32_t contentSize;
	char * content;
	*/
	int32_t offset = 0;
	memcpy(&(aMessage->type), aSerializable.Data + offset, sizeof(aMessage->type));
	offset += sizeof(aMessage->type);
	memcpy(&(aMessage->auxiliar), aSerializable.Data + offset, sizeof(aMessage->auxiliar));
	offset += sizeof(aMessage->auxiliar);
	memcpy(&(aMessage->sectorRequest), aSerializable.Data + offset, sizeof(aMessage->sectorRequest));
	offset += sizeof(aMessage->sectorRequest);
	memcpy(&(aMessage->contentSize), aSerializable.Data + offset, sizeof(aMessage->contentSize));
	offset += sizeof(aMessage->contentSize);
	aMessage->content = (char *)calloc(aMessage->contentSize, sizeof(char));
	memcpy(aMessage->content, aSerializable.Data + offset, aMessage->contentSize * sizeof(char));
}

uint32_t getSizeFromHeader(char * headerBuffer)
{
	uint32_t offset = sizeof(TypeMsg) + sizeof(uint32_t) + sizeof(int32_t);
	uint32_t * ptr = (uint32_t *)(headerBuffer + offset);
	return (*ptr);
}

int32_t getSectorFromHeader(char * headerBuffer)
{
	uint32_t offset = sizeof(TypeMsg) + sizeof(uint32_t);
	int32_t * ptr = (int32_t *)(headerBuffer + offset);
	return (*ptr);
}

TypeMsg getTypeFromHeader(char * headerBuffer)
{
	uint32_t offset = 0;
	TypeMsg * ptr = (TypeMsg *)(headerBuffer + offset);
	return (*ptr);
}

void Message_Copy(Message * msgTo, Message msgFrom)
{
	msgTo->type = msgFrom.type;
	msgTo->sectorRequest = msgFrom.sectorRequest;
	msgTo->contentSize = msgFrom.contentSize;
	msgTo->auxiliar    = msgFrom.auxiliar;
	msgTo->content = NULL;
	if ((msgFrom.contentSize > 0) && (msgFrom.content != NULL)) {
		msgTo->content = calloc(msgFrom.contentSize, sizeof(char));
		memcpy(msgTo->content, msgFrom.content, msgFrom.contentSize);
	}
}

void Message_Free(Message * aMsg)
{
	if ((aMsg->contentSize > 0) && (aMsg->content != NULL))
		free(aMsg->content);
	aMsg->contentSize = 0;
	aMsg->content = NULL;
}
